package zy.service.stock.check.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import zy.dao.approve.ApproveRecordDAO;
import zy.dao.base.product.ProductDAO;
import zy.dao.base.size.SizeDAO;
import zy.dao.stock.check.CheckDAO;
import zy.dao.stock.data.DataDAO;
import zy.dao.stock.loss.LossDAO;
import zy.dao.stock.overflow.OverflowDAO;
import zy.dao.stock.useable.UseableDAO;
import zy.dto.common.ProductDto;
import zy.dto.stock.check.CheckDiffDto;
import zy.entity.PageData;
import zy.entity.PageInfo;
import zy.entity.approve.T_Approve_Record;
import zy.entity.base.product.T_Base_Barcode;
import zy.entity.base.product.T_Base_Product;
import zy.entity.base.size.T_Base_Size;
import zy.entity.base.size.T_Base_SizeList;
import zy.entity.stock.T_Stock_Import;
import zy.entity.stock.check.T_Stock_Batch;
import zy.entity.stock.check.T_Stock_Check;
import zy.entity.stock.check.T_Stock_CheckList;
import zy.entity.stock.data.T_Stock_DataBill;
import zy.entity.stock.data.T_Stock_DataView;
import zy.entity.stock.loss.T_Stock_Loss;
import zy.entity.stock.loss.T_Stock_LossList;
import zy.entity.stock.overflow.T_Stock_Overflow;
import zy.entity.stock.overflow.T_Stock_OverflowList;
import zy.entity.sys.set.T_Sys_Set;
import zy.entity.sys.user.T_Sys_User;
import zy.service.stock.check.CheckService;
import zy.util.CommonUtil;
import zy.util.DateUtil;
import zy.util.StringUtil;
import zy.vo.common.SizeHorizontalVO;
import zy.vo.stock.CheckVO;

@Service
public class CheckServiceImpl implements CheckService{
	@Resource
	private CheckDAO checkDAO;
	
	@Resource
	private ApproveRecordDAO approveRecordDAO;
	
	@Resource
	private DataDAO dataDAO;
	
	@Resource
	private ProductDAO productDAO;
	
	@Resource
	private SizeDAO sizeDAO;
	
	@Resource
	private LossDAO lossDAO;
	
	@Resource
	private OverflowDAO overflowDAO;
	
	@Resource
	private UseableDAO useableDAO;
	
	@Override
	public PageData<T_Stock_Batch> batch_page(Map<String, Object> params) {
		Object companyid = params.get(CommonUtil.COMPANYID);
		Object pageSize = params.get(CommonUtil.PAGESIZE);
		Object pageIndex = params.get(CommonUtil.PAGEINDEX);
		if (companyid == null) {
			throw new IllegalArgumentException("连接超时，请重新登录!");
		}
		Integer _pageSize = (Integer)pageSize;
		Integer _pageIndex = (Integer)pageIndex;
		
		Integer totalCount = checkDAO.batch_count(params);
		PageInfo pageInfo = new PageInfo(totalCount, _pageSize, _pageIndex);
		params.put(CommonUtil.START, (_pageIndex-1)*_pageSize);
		params.put(CommonUtil.END, _pageSize);
		
		List<T_Stock_Batch> list = checkDAO.batch_list(params);
		PageData<T_Stock_Batch> pageData = new PageData<T_Stock_Batch>();
		pageData.setPageInfo(pageInfo);
		pageData.setList(list);
		return pageData;
	}
	
	@Override
	public T_Stock_Batch batch_load(Integer ba_id) {
		T_Stock_Batch batch = checkDAO.batch_load(ba_id);
		if(batch != null){
			T_Approve_Record approve_Record = approveRecordDAO.load(batch.getBa_number(), batch.getCompanyid());
			if(approve_Record != null){
				batch.setAr_describe(approve_Record.getAr_describe());
			}
		}
		return batch;
	}

	/**
	 * 判断两个数组是否前者包含后者子集
	 * @param mainList
	 * @param subList
	 * @return
	 */
	private static boolean ContainPart(List<String> mainList,List<String> subList){
		for(int i=0;i<subList.size();i++){
			if(mainList.contains(subList.get(i))){
				return true;
			}
		}
		return false;
	}
	
	@Override
	@Transactional
	public void batch_save(T_Stock_Batch batch, T_Sys_User user) {
		if(batch == null){
			throw new IllegalArgumentException("参数不能为null");
		}
		if(StringUtil.isEmpty(batch.getBa_dp_code())){
			throw new IllegalArgumentException("盘点仓库不能为空");
		}
		if(StringUtil.isEmpty(batch.getBa_manager())){
			throw new IllegalArgumentException("经办人不能为空");
		}
		if(StringUtil.isEmpty(batch.getBa_scope())){
			throw new IllegalArgumentException("盘点范围不能为空");
		}
		if(batch.getBa_scope().intValue() != 0 && StringUtil.isEmpty(batch.getBa_scope_code())){
			throw new IllegalArgumentException("盘点项目不能为空");
		}
		batch.setCompanyid(user.getCompanyid());
		batch.setBa_us_id(user.getUs_id());
		batch.setBa_ar_state(CommonUtil.AR_STATE_NOTAPPROVE);
		batch.setBa_isexec(CommonUtil.EXEC_STATE_UNDO);
		batch.setBa_date(DateUtil.getCurrentTime());
		//1.盘点批次检测
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("ba_dp_code", batch.getBa_dp_code());
		params.put("companyid", batch.getCompanyid());
		List<T_Stock_Batch> undoBatchs = checkDAO.batch_check(params);
		boolean hasUncheck = false;
		if (undoBatchs != null && undoBatchs.size() > 0) {
			for (T_Stock_Batch item : undoBatchs) {//盘点范围0全场盘点1类别盘点2品牌盘点3单品盘点4年份盘点5季节盘点
				if(item.getBa_scope().intValue() == 0){
					hasUncheck = true;
					break;
				}else {
					if(ContainPart(Arrays.asList(item.getBa_scope_code().split(",")), Arrays.asList(batch.getBa_scope_code().split(",")))){
						hasUncheck = true;
						break;
					}
				}
			}
		}
		if(hasUncheck){
			throw new RuntimeException("你选择的仓库之前有未完成的盘点，请先完成或删除盘点后再对该仓库进行盘点操作!");
		}
		checkDAO.batch_save(batch);
	}
	
	@Override
	@Transactional
	public T_Stock_Batch batch_approve(String number, T_Approve_Record record, T_Sys_User user) {
		if (number == null) {
			throw new IllegalArgumentException("参数number不能为null");
		}
		T_Stock_Batch batch = checkDAO.check(number, user.getCompanyid());
		if(batch == null){
			throw new RuntimeException("单据不存在");
		}
		if(!CommonUtil.AR_STATE_NOTAPPROVE.equals(batch.getBa_ar_state())){
			throw new RuntimeException("单据已经审核");
		}
		//1.更新单据审核状态
		batch.setBa_ar_state(record.getAr_state());
		checkDAO.batch_updateApprove(batch);
		//2.保存审核记录表
		record.setAr_number(number);
		record.setAr_sysdate(DateUtil.getCurrentTime());
		record.setAr_us_name(user.getUs_name());
		record.setAr_type("t_stock_batch");
		record.setCompanyid(user.getCompanyid());
		approveRecordDAO.save(record);
		return batch;
	}
	
	@Override
	@Transactional
	public void batch_delete(String number, Integer companyid) {
		if (number == null) {
			throw new IllegalArgumentException("参数number不能为null");
		}
		T_Stock_Batch batch = checkDAO.check(number, companyid);
		if(batch == null){
			throw new RuntimeException("单据不存在");
		}
		if(!CommonUtil.AR_STATE_NOTAPPROVE.equals(batch.getBa_ar_state()) && !CommonUtil.AR_STATE_FAIL.equals(batch.getBa_ar_state())){
			throw new RuntimeException("单据已审核通过不能删除！");
		}
		checkDAO.batch_delete(number, companyid);
	}

	@Override
	public List<T_Stock_Check> check_list4exec(String ba_number,Integer companyid) {
		return checkDAO.check_list4exec(ba_number, companyid);
	}
	
	@Override
	public T_Stock_Check check_load(String ck_number,Integer companyid) {
		return checkDAO.check_load(ck_number, companyid);
	}
	
	@Override
	public List<T_Stock_CheckList> check_detail_list_all(Map<String, Object> params) {
		return checkDAO.check_detail_list_all(params);
	}
	
	@Override
	public List<T_Stock_CheckList> check_detail_sum_all(Map<String, Object> params) {
		return checkDAO.check_detail_sum_all(params);
	}
	
	@Override
	public Map<String, Object> check_detail_size_title_all(Map<String, Object> params) {
		Integer companyid = (Integer)params.get(CommonUtil.COMPANYID);
		List<String> szgCodes = checkDAO.check_detail_szgcode_all(params);
		if(szgCodes==null||szgCodes.size()==0){
			Map<String, Object> resultMap = new HashMap<String, Object>();
			resultMap.put("titles", new ArrayList<List<String>>());
			return resultMap;
		}
		List<T_Base_SizeList> sizeGroupList = sizeDAO.listBySzg(szgCodes, companyid);
		return SizeHorizontalVO.getJsonSizeTitles(sizeGroupList);
	}
	
	@Override
	public Map<String, Object> check_detail_size_all(Map<String, Object> params) {
		Integer companyid = (Integer)params.get(CommonUtil.COMPANYID);
		List<String> szgCodes = checkDAO.check_detail_szgcode_all(params);
		if(szgCodes==null||szgCodes.size()==0){
			return new HashMap<String, Object>();
		}
		List<T_Base_SizeList> sizeGroupList = sizeDAO.listBySzg(szgCodes, companyid);
		params.put(CommonUtil.SIDX, "ckl_pd_code,ckl_cr_code,ckl_br_code");
		params.put(CommonUtil.SORD, "ASC");
		List<T_Stock_CheckList> temps = checkDAO.check_detail_list_all(params);
		return CheckVO.getJsonSizeData(sizeGroupList, temps);
	}
	
	@Override
	public List<T_Stock_CheckList> check_detail_list(Map<String, Object> params) {
		return checkDAO.check_detail_list(params);
	}
	
	@Override
	public List<T_Stock_CheckList> check_detail_sum(Map<String, Object> params) {
		return checkDAO.check_detail_sum(params);
	}
	
	@Override
	public Map<String, Object> check_detail_size_title(Map<String, Object> params) {
		Integer companyid = (Integer)params.get(CommonUtil.COMPANYID);
		List<String> szgCodes = checkDAO.check_detail_szgcode(params);
		if(szgCodes==null||szgCodes.size()==0){
			Map<String, Object> resultMap = new HashMap<String, Object>();
			resultMap.put("titles", new ArrayList<List<String>>());
			return resultMap;
		}
		List<T_Base_SizeList> sizeGroupList = sizeDAO.listBySzg(szgCodes, companyid);
		return SizeHorizontalVO.getJsonSizeTitles(sizeGroupList);
	}
	
	@Override
	public Map<String, Object> check_detail_size(Map<String, Object> params) {
		Integer companyid = (Integer)params.get(CommonUtil.COMPANYID);
		List<String> szgCodes = checkDAO.check_detail_szgcode(params);
		if(szgCodes==null||szgCodes.size()==0){
			return new HashMap<String, Object>();
		}
		List<T_Base_SizeList> sizeGroupList = sizeDAO.listBySzg(szgCodes, companyid);
		params.put(CommonUtil.SIDX, "ckl_pd_code,ckl_cr_code,ckl_br_code");
		params.put(CommonUtil.SORD, "ASC");
		List<T_Stock_CheckList> temps = checkDAO.check_detail_list(params);
		return CheckVO.getJsonSizeData(sizeGroupList, temps);
	}
	
	@Override
	public List<T_Stock_CheckList> check_temp_list(Map<String, Object> params) {
		return checkDAO.check_temp_list(params);
	}

	@Override
	public List<T_Stock_CheckList> check_temp_sum(Map<String, Object> params) {
		return checkDAO.check_temp_sum(params);
	}

	@Override
	public Map<String, Object> check_temp_size_title(Map<String, Object> params) {
		Integer companyid = (Integer)params.get(CommonUtil.COMPANYID);
		List<String> szgCodes = checkDAO.temp_szgcode(params);
		if(szgCodes==null||szgCodes.size()==0){
			Map<String, Object> resultMap = new HashMap<String, Object>();
			resultMap.put("titles", new ArrayList<List<String>>());
			return resultMap;
		}
		List<T_Base_SizeList> sizeGroupList = sizeDAO.listBySzg(szgCodes, companyid);
		return SizeHorizontalVO.getJsonSizeTitles(sizeGroupList);
	}

	@Override
	public Map<String, Object> check_temp_size(Map<String, Object> params) {
		Integer companyid = (Integer)params.get(CommonUtil.COMPANYID);
		List<String> szgCodes = checkDAO.temp_szgcode(params);
		if(szgCodes==null||szgCodes.size()==0){
			return new HashMap<String, Object>();
		}
		List<T_Base_SizeList> sizeGroupList = sizeDAO.listBySzg(szgCodes, companyid);
		params.put(CommonUtil.SIDX, "ckl_pd_code,ckl_cr_code,ckl_br_code");
		params.put(CommonUtil.SORD, "ASC");
		List<T_Stock_CheckList> temps = checkDAO.check_temp_list(params);
		return CheckVO.getJsonSizeData(sizeGroupList, temps);
	}

	@Override
	@Transactional
	public Map<String, Object> check_temp_save_bybarcode(Map<String, Object> params) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		String barcode = (String)params.get("barcode");
		Integer amount = (Integer)params.get("amount");
		T_Sys_User user = (T_Sys_User)params.get("user");
		String ba_number = (String)params.get("ba_number");
		String dp_code = (String)params.get("dp_code");
		Integer ckl_isrepair = (Integer)params.get("ckl_isrepair");
		Integer ba_scope = (Integer)params.get("ba_scope");
		String ba_scope_code = (String)params.get("ba_scope_code");
		T_Base_Barcode base_Barcode = productDAO.loadBarcode(barcode, user.getCompanyid());
		if(base_Barcode == null){
			resultMap.put("result", 3);//条码不存在
			return resultMap;
		}
		T_Stock_CheckList temp = checkDAO.check_temp_loadBySubCode(base_Barcode.getBc_subcode(), ba_number, ckl_isrepair,user.getUs_id(), user.getCompanyid());
		if (temp != null) {//临时表存在则直接更新数量
			temp.setCkl_amount(temp.getCkl_amount()+amount);
			checkDAO.check_temp_update(temp);
			resultMap.put("result", 1);//update
			resultMap.put("temp", temp);
			return resultMap;
		}
		T_Base_Product base_Product = checkDAO.load_product(base_Barcode.getBc_pd_code(), user.getCompanyid());
		if(ba_scope.intValue() != 0){//验证盘点范围
			List<String> scope_codes = Arrays.asList(ba_scope_code.split(","));
			boolean inScope = false;
			if(ba_scope.intValue() == 1){//类别
				inScope = scope_codes.contains(base_Product.getPd_tp_code());
			}else if(ba_scope.intValue() == 2){//品牌
				inScope = scope_codes.contains(base_Product.getPd_bd_code());
			}else if(ba_scope.intValue() == 3){//单品
				inScope = scope_codes.contains(base_Product.getPd_code());
			}else if(ba_scope.intValue() == 4){//年份
				inScope = scope_codes.contains(StringUtil.trimString(base_Product.getPd_year()));
			}else if(ba_scope.intValue() == 5){//季节
				inScope = scope_codes.contains(base_Product.getPd_season());
			}
			if(!inScope){
				throw new RuntimeException("不在本次盘点范围");
			}
		}
		temp = new T_Stock_CheckList();
		temp.setCkl_pd_code(base_Barcode.getBc_pd_code());
		temp.setCkl_cr_code(base_Barcode.getBc_color());
		temp.setCkl_sz_code(base_Barcode.getBc_size());
		temp.setCkl_szg_code(base_Product.getPd_szg_code());
		temp.setCkl_br_code(base_Barcode.getBc_bra());
		temp.setCkl_sub_code(temp.getCkl_pd_code()+temp.getCkl_cr_code()+temp.getCkl_sz_code()+temp.getCkl_br_code());
		temp.setCkl_amount(amount);
		temp.setCkl_unitprice(base_Product.getPd_cost_price());
		temp.setCkl_retailprice(base_Product.getPd_sell_price());
		temp.setCkl_remark("");
		temp.setCkl_ba_number(ba_number);
		temp.setCkl_isrepair(ckl_isrepair);
		temp.setCkl_us_id(user.getUs_id());
		temp.setCompanyid(user.getCompanyid());
		checkDAO.check_temp_save(temp);
		temp.setPd_no(base_Product.getPd_no());
		temp.setPd_name(base_Product.getPd_name());
		temp.setPd_unit(base_Product.getPd_unit());
		temp.setBd_name(base_Product.getPd_bd_name());
		temp.setTp_name(base_Product.getPd_tp_name());
		temp.setCr_name(base_Barcode.getBc_colorname());
		temp.setSz_name(base_Barcode.getBc_sizename());
		temp.setBr_name(base_Barcode.getBc_braname());
		temp.setCkl_stock_amount(dataDAO.queryStockAmount(temp.getCkl_sub_code(), dp_code, user.getCompanyid()));
		resultMap.put("result", 2);//add
		resultMap.put("temp", temp);
		return resultMap;
	}
	
	@Override
	public PageData<T_Base_Product> page_product(Map<String, Object> param) {
		Object companyid = param.get(CommonUtil.COMPANYID);
		Object pageSize = param.get(CommonUtil.PAGESIZE);
		Object pageIndex = param.get(CommonUtil.PAGEINDEX);
		if (companyid == null) {
			throw new IllegalArgumentException("连接超时，请重新登录!");
		}
		Integer ba_scope = (Integer)param.get("ba_scope");
		String ba_scope_code = (String)param.get("ba_scope_code");
		if(ba_scope.intValue() != 0){
			param.put("scope_codes", Arrays.asList(ba_scope_code.split(",")));
		}
		Integer _pageSize = (Integer)pageSize;
		Integer _pageIndex = (Integer)pageIndex;
		
		Integer totalCount = checkDAO.count_product(param);
		PageInfo pageInfo = new PageInfo(totalCount, _pageSize, _pageIndex);
		param.put(CommonUtil.START, (_pageIndex-1)*_pageSize);
		param.put(CommonUtil.END, _pageSize);
		
		List<T_Base_Product> list = checkDAO.list_product(param);
		PageData<T_Base_Product> pageData = new PageData<T_Base_Product>();
		pageData.setPageInfo(pageInfo);
		pageData.setList(list);
		return pageData;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Map<String, Object> temp_loadproduct(Map<String, Object> params) {
		Integer companyid = (Integer)params.get(CommonUtil.COMPANYID);
		T_Sys_Set sysSet = (T_Sys_Set)params.get(CommonUtil.KEY_SYSSET);
		String pd_code = (String)params.get("pd_code");
		String dp_code = (String)params.get("dp_code");
		if (companyid == null) {
			throw new IllegalArgumentException("连接超时，请重新登录!");
		}
		Map<String, Object> resultMap = new HashMap<String, Object>();
		T_Base_Product base_Product = checkDAO.load_product(pd_code, companyid);
		Map<String, Object> product = new HashMap<String, Object>();
		product.put("pd_id", base_Product.getPd_id());
		product.put("pd_code", base_Product.getPd_code());
		product.put("pd_no", base_Product.getPd_no());
		product.put("pd_name", base_Product.getPd_name());
		product.put("pd_szg_code", base_Product.getPd_szg_code());
		product.put("pd_unit", base_Product.getPd_unit());
		product.put("pd_year", base_Product.getPd_year());
		product.put("pd_season", base_Product.getPd_season());
		product.put("pd_sell_price", base_Product.getPd_sell_price());
		product.put("pdm_buy_price", base_Product.getPd_buy_price());
		product.put("pdm_cost_price", base_Product.getPd_cost_price());
		product.put("pd_bd_name", base_Product.getPd_bd_name());
		product.put("pd_tp_name", base_Product.getPd_tp_name());
		product.put("unitPrice", base_Product.getPd_cost_price());
		product.put("pdm_img_path", StringUtil.trimString(base_Product.getPdm_img_path()));
		resultMap.put("product", product);
		params.put("szg_code", base_Product.getPd_szg_code());
		Map<String, Object> productMap = checkDAO.load_product_size(params);
		List<T_Base_Size> sizes=(List<T_Base_Size>)productMap.get("sizes");
		List<ProductDto> inputs=(List<ProductDto>)productMap.get("inputs");
		List<ProductDto> temps=(List<ProductDto>)productMap.get("temps");
		List<ProductDto> stocks=(List<ProductDto>)productMap.get("stocks");
		Map<String,Object> usableStockMap = null;
		if (sysSet.getSt_useable() != null && sysSet.getSt_useable().intValue() == 1) {
			usableStockMap = useableDAO.loadUseableStock(pd_code, dp_code, companyid);
		}
		resultMap.putAll(SizeHorizontalVO.buildJsonProductInput(pd_code, sizes, inputs, stocks, temps, usableStockMap));
		return resultMap;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	@Transactional
	public void check_temp_save(Map<String, Object> params) {
		List<T_Stock_CheckList> temps = (List<T_Stock_CheckList>)params.get("temps");
		if (temps != null && temps.size() > 0) {
			List<T_Stock_CheckList> temps_add = new ArrayList<T_Stock_CheckList>();
			List<T_Stock_CheckList> temps_update = new ArrayList<T_Stock_CheckList>();
			List<T_Stock_CheckList> temps_del = new ArrayList<T_Stock_CheckList>();
			for (T_Stock_CheckList item : temps) {
				if ("add".equals(item.getOperate_type())){
					temps_add.add(item);
				}else if("update".equals(item.getOperate_type())){
					temps_update.add(item);
				}
			}
			if (temps_add.size() > 0) {
				checkDAO.check_temp_save(temps_add);
			}
			if (temps_update.size() > 0) {
				checkDAO.check_temp_update(temps_update);
			}
			if (temps_del.size() > 0) {
				checkDAO.check_temp_del(temps_del);
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	@Override
	@Transactional
	public void check_temp_import(Map<String, Object> params) {
		List<String[]> datas = (List<String[]>)params.get("datas");
		T_Sys_User user = (T_Sys_User)params.get("user");
		String ba_number = (String)params.get("ba_number");
		Integer ckl_isrepair = (Integer)params.get("ckl_isrepair");
		List<String> barcodes = new ArrayList<String>();
		Map<String, Integer> data_amount = new HashMap<String, Integer>();
		for (String[] data : datas) {
			barcodes.add(data[0]);
			data_amount.put(data[0], Integer.parseInt(data[1]));
		}
		List<T_Stock_Import> imports = checkDAO.check_temp_listByImport(barcodes, user.getCompanyid());
		if (imports == null || imports.size() == 0) {
			throw new RuntimeException("无数据可导入");
		}
		Map<String, T_Stock_CheckList> tempsMap = new HashMap<String, T_Stock_CheckList>();
		List<T_Stock_CheckList> temps = checkDAO.check_temp_list_forimport(ba_number,ckl_isrepair,user.getUs_id(), user.getCompanyid());
		for (T_Stock_CheckList temp : temps) {
			tempsMap.put(temp.getCkl_sub_code(), temp);
		}
		List<T_Stock_CheckList> temps_add = new ArrayList<T_Stock_CheckList>();
		List<T_Stock_CheckList> temps_update = new ArrayList<T_Stock_CheckList>();
		for (T_Stock_Import item : imports) {
			if(tempsMap.containsKey(item.getBc_subcode())){//临时表已存在，更新数量
				T_Stock_CheckList temp = tempsMap.get(item.getBc_subcode());
				temp.setCkl_amount(temp.getCkl_amount()+data_amount.get(item.getBc_barcode()));
				temps_update.add(temp);
			}else {//临时表不存在，新增数据
				T_Stock_CheckList temp = new T_Stock_CheckList();
				temp.setCkl_pd_code(item.getBc_pd_code());
				temp.setCkl_sub_code(item.getBc_subcode());
				temp.setCkl_sz_code(item.getBc_size());
				temp.setCkl_szg_code(item.getPd_szg_code());
				temp.setCkl_cr_code(item.getBc_color());
				temp.setCkl_br_code(item.getBc_bra());
				temp.setCkl_amount(data_amount.get(item.getBc_barcode()));
				temp.setCkl_unitprice(item.getUnit_price());
				temp.setCkl_retailprice(item.getPd_sell_price());
				temp.setCkl_remark("");
				temp.setCkl_ba_number(ba_number);
				temp.setCkl_isrepair(ckl_isrepair);
				temp.setCkl_us_id(user.getUs_id());
				temp.setCompanyid(user.getCompanyid());
				temps_add.add(temp);
			}
		}
		if (temps_add.size() > 0) {
			checkDAO.check_temp_save(temps_add);
		}
		if (temps_update.size() > 0) {
			checkDAO.check_temp_updateById(temps_update);
		}
	}
	
	@Override
	@Transactional
	public void check_temp_repair(Map<String, Object> params) {
		T_Sys_User user = (T_Sys_User)params.get("user");
		String ba_number = (String)params.get("ba_number");
		String repair_type = (String)params.get("repair_type");//1-累加，2-覆盖
		
		T_Stock_Batch batch = checkDAO.check(ba_number, user.getCompanyid());
		if(batch == null){
			throw new RuntimeException("单据不存在");
		}
		if(!CommonUtil.EXEC_STATE_UNDO.equals(batch.getBa_isexec())){
			throw new RuntimeException("盘点批次已经处理");
		}
		List<T_Stock_CheckList> temps_all = checkDAO.check_temp_list_forrepair(ba_number,user.getUs_id(), user.getCompanyid());
		List<T_Stock_CheckList> temps = new ArrayList<T_Stock_CheckList>();
		List<T_Stock_CheckList> temps_repair = new ArrayList<T_Stock_CheckList>();
		for (T_Stock_CheckList item : temps_all) {
			if(item.getCkl_isrepair().intValue() == 0){
				temps.add(item);
			}else if(item.getCkl_isrepair().intValue() == 1){
				temps_repair.add(item);
			}
		}
		if (temps_repair.size() == 0) {
			throw new RuntimeException("无补盘数据可导入");
		}
		List<T_Stock_CheckList> temps_update = new ArrayList<T_Stock_CheckList>();
		List<T_Stock_CheckList> temps_del = new ArrayList<T_Stock_CheckList>();
		boolean exist = false;
		T_Stock_CheckList srcCheckList = null;
		for (T_Stock_CheckList item : temps_repair) {
			exist = false;
			srcCheckList = null;
			for (T_Stock_CheckList srcItem : temps) {
				if (item.getCkl_sub_code().equals(srcItem.getCkl_sub_code())) {
					exist = true;
					srcCheckList = srcItem;
					break;
				}
			}
			if(exist){//临时表存在补盘数据
				if("1".equals(repair_type)){//1-累加
					srcCheckList.setCkl_amount(srcCheckList.getCkl_amount()+item.getCkl_amount());
				}else if("2".equals(repair_type)){//2-覆盖
					srcCheckList.setCkl_amount(item.getCkl_amount());
				}
				temps_update.add(srcCheckList);
				temps_del.add(item);
			}else {
				item.setCkl_isrepair(0);
				temps_update.add(item);
			}
		}
		if (temps_update.size() > 0) {
			checkDAO.check_temp_update_repair(temps_update);
		}
		if(temps_del.size() > 0){
			checkDAO.check_temp_del(temps_del);
		}
	}
	
	@Override
	@Transactional
	public void check_temp_updateAmount(T_Stock_CheckList temp) {
		checkDAO.check_temp_update(temp);
	}
	
	@Override
	@Transactional
	public void check_temp_updateRemarkById(T_Stock_CheckList temp) {
		checkDAO.check_temp_updateRemarkById(temp);
	}
	
	@Override
	@Transactional
	public void check_temp_updateRemarkByPdCode(T_Stock_CheckList temp) {
		checkDAO.check_temp_updateRemarkByPdCode(temp);
	}
	
	@Override
	@Transactional
	public void check_temp_del(Integer ckl_id) {
		checkDAO.check_temp_del(ckl_id);
	}
	
	@Override
	@Transactional
	public void check_temp_delByPiCode(T_Stock_CheckList temp) {
		if (temp.getCompanyid() == null) {
			throw new IllegalArgumentException("连接超时，请重新登录!");
		}
		if (temp.getCkl_us_id() == null) {
			throw new IllegalArgumentException("参数us_id不能为null");
		}
		checkDAO.check_temp_delByPiCode(temp);
	}
	
	@Override
	@Transactional
	public void check_temp_clear(String ba_number,Integer ckl_isrepair,Integer us_id,Integer companyid) {
		checkDAO.check_temp_clear(ba_number, ckl_isrepair, us_id, companyid);
	}
	
	@Override
	@Transactional
	public void check_temp_clear_all(String ba_number,Integer us_id,Integer companyid) {
		checkDAO.check_temp_clear_all(ba_number, us_id, companyid);
	}
	
	@Override
	@Transactional
	public void check_save(T_Stock_Check check, T_Sys_User user) {
		if(check == null){
			throw new IllegalArgumentException("参数不能为null");
		}
		if(StringUtil.isEmpty(check.getCk_manager())){
			throw new IllegalArgumentException("经办人不能为空");
		}
		check.setCompanyid(user.getCompanyid());
		check.setCk_us_id(user.getUs_id());
		check.setCk_isdraft(0);
		check.setCk_isexec(CommonUtil.EXEC_STATE_UNDO);
		check.setCk_date(DateUtil.getCurrentTime());
		
		T_Stock_Batch batch = checkDAO.check(check.getCk_ba_number(),user.getUs_id(), user.getCompanyid());
		if(batch == null){
			throw new RuntimeException("单据不存在");
		}
		if(!CommonUtil.EXEC_STATE_UNDO.equals(batch.getBa_isexec())){
			throw new RuntimeException("盘点批次已经处理");
		}
		if(StringUtil.isNotEmpty(batch.getCk_number())){
			throw new RuntimeException("盘点单据已提交");
		}
		//1.查临时表
		List<T_Stock_CheckList> temps = checkDAO.check_temp_list_forsave(check.getCk_ba_number(),check.getCk_dp_code(),user.getUs_id(), user.getCompanyid());
		if(temps == null || temps.size() == 0){
			throw new RuntimeException("单据已保存，请勿重复提交");
		}
		//2.保存单据
		int ck_amount = 0;
		int ck_stockamount = 0;
		double ck_money = 0d;
		double ck_retailmoney = 0d;
		for (T_Stock_CheckList temp : temps) {
			ck_amount += temp.getCkl_amount();
			ck_stockamount += temp.getCkl_stock_amount();
			ck_money += temp.getCkl_amount() * temp.getCkl_unitprice();
			ck_retailmoney += temp.getCkl_amount() * temp.getCkl_retailprice();
		}
		check.setCk_amount(ck_amount);
		check.setCk_stockamount(ck_stockamount);
		check.setCk_money(ck_money);
		check.setCk_retailmoney(ck_retailmoney);
		checkDAO.check_save(check, temps);
	}

	@Override
	@Transactional
	public void check_recheck(String ck_number, T_Sys_User user) {
		T_Stock_Check check = checkDAO.check_load(ck_number, user.getCompanyid());
		if(check == null){
			throw new RuntimeException("单据已重盘");
		}
		if(check.getCk_isexec().intValue() != 0){
			throw new RuntimeException("盘点已经处理，不能重盘");
		}
		List<T_Stock_CheckList> details = checkDAO.check_detail_list_forsavetemp(check.getCk_number(), user.getCompanyid());
		for (T_Stock_CheckList item : details) {
			item.setCkl_us_id(check.getCk_us_id());
			item.setCkl_isrepair(0);
		}
		checkDAO.check_delete(check.getCk_number(), user.getCompanyid());
		checkDAO.check_temp_clear_all(check.getCk_ba_number(), check.getCk_us_id(), user.getCompanyid());
		checkDAO.check_temp_save(details);
	}

	@Override
	public List<T_Stock_DataView> check_missing(Map<String, Object> params) {
		Integer ba_scope = (Integer)params.get("ba_scope");
		String ba_scope_code = (String)params.get("ba_scope_code");
		if(ba_scope.intValue() != 0){
			params.put("scope_codes", Arrays.asList(ba_scope_code.split(",")));
		}
		return checkDAO.check_missing(params);
	}
	
	@Override
	@Transactional
	public void check_exec(String ba_number,Integer ba_isexec,T_Sys_User user){
		T_Stock_Batch batch = checkDAO.check(ba_number, user.getCompanyid());
		if(batch == null){
			throw new RuntimeException("单据不存在");
		}
		if(!CommonUtil.EXEC_STATE_UNDO.equals(batch.getBa_isexec())){
			throw new RuntimeException("盘点批次已经处理");
		}
		List<T_Stock_Check> checks = checkDAO.check_list4exec(ba_number, user.getCompanyid());
		if (checks.size() == 0) {
			throw new RuntimeException("发现有未录入完成或没有录入数据!");
		}
		boolean canExec = true;
		for (T_Stock_Check check : checks) {
			if(StringUtil.isEmpty(check.getCk_number())){
				canExec = false;
			}
		}
		if(!canExec){
			throw new RuntimeException("发现有未录入完成或没有录入数据!");
		}
		List<T_Stock_CheckList> details = checkDAO.check_detail_list_stockamount(ba_number,batch.getBa_dp_code(),user.getCompanyid());
		checkDAO.check_detail_updateStockAmount(details);
		//将details--->inputDetails,由于details为多人录入，其中可能存在相同subcode的数据，去重累计，用于生成报损单，报溢单
		List<T_Stock_CheckList> inputDetails = new ArrayList<T_Stock_CheckList>();
		for (T_Stock_CheckList item : details) {
			boolean exist = false;
			T_Stock_CheckList existItem = null;
			for (T_Stock_CheckList temp : inputDetails) {
				if(temp.getCkl_sub_code().equals(item.getCkl_sub_code())){
					exist = true;
					existItem = temp;
					break;
				}
			}
			if(exist){
				existItem.setCkl_amount(existItem.getCkl_amount()+item.getCkl_amount());
			}else {
				inputDetails.add(item);
			}
		}
		List<T_Stock_CheckList> missingDetails = null;
		if(ba_isexec.intValue() == 1){//全部处理-查询漏盘数据保存到子表
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("ba_number", ba_number);
			params.put("companyid", user.getCompanyid());
			params.put("ba_scope", batch.getBa_scope());
			params.put("dp_code", batch.getBa_dp_code());
			if(batch.getBa_scope().intValue() != 0){
				params.put("scope_codes", Arrays.asList(batch.getBa_scope_code().split(",")));
			}
			missingDetails = checkDAO.check_missing_execall(params);
			for (T_Stock_CheckList item : missingDetails) {
				item.setCkl_ba_number(ba_number);
				item.setCkl_amount(0);
				item.setCkl_remark("");
				item.setCompanyid(user.getCompanyid());
			}
			if (missingDetails != null && missingDetails.size() > 0) {
				inputDetails.addAll(missingDetails);
			}
		}
		//生成盘点子表数据(合并录入的数据，全部处理则保存漏盘数据)
		checkDAO.check_detail_all_save(inputDetails);
		
		T_Stock_Loss loss = null;
		T_Stock_Overflow overflow = null;
		int lo_amount = 0, of_amount = 0;
		double lo_money = 0d, of_money = 0d;
		int ba_amount = 0, ba_stockamount = 0;
		double ba_costmoney = 0d, ba_retailmoney = 0d;
		List<T_Stock_LossList> lossLists = new ArrayList<T_Stock_LossList>();
		List<T_Stock_OverflowList> overflowLists = new ArrayList<T_Stock_OverflowList>();
		for (T_Stock_CheckList item : inputDetails) {
			if (item.getCkl_amount() < item.getCkl_stock_amount()) {// 报损
				T_Stock_LossList lossItem = new T_Stock_LossList();
				lossItem.setLol_pd_code(item.getCkl_pd_code());
				lossItem.setLol_sub_code(item.getCkl_sub_code());
				lossItem.setLol_sz_code(item.getCkl_sz_code());
				lossItem.setLol_szg_code(item.getCkl_szg_code());
				lossItem.setLol_cr_code(item.getCkl_cr_code());
				lossItem.setLol_br_code(item.getCkl_br_code());
				lossItem.setLol_amount(item.getCkl_stock_amount()-item.getCkl_amount());
				lossItem.setLol_unitprice(item.getCkl_unitprice());
				lossItem.setLol_remark("");
				lossItem.setCompanyid(user.getCompanyid());
				lo_amount += lossItem.getLol_amount();
				lo_money += lossItem.getLol_amount()* lossItem.getLol_unitprice();
				lossLists.add(lossItem);
			} else if (item.getCkl_amount() > item.getCkl_stock_amount()) {// 报溢
				T_Stock_OverflowList overflowItem = new T_Stock_OverflowList();
				overflowItem.setOfl_pd_code(item.getCkl_pd_code());
				overflowItem.setOfl_sub_code(item.getCkl_sub_code());
				overflowItem.setOfl_sz_code(item.getCkl_sz_code());
				overflowItem.setOfl_szg_code(item.getCkl_szg_code());
				overflowItem.setOfl_cr_code(item.getCkl_cr_code());
				overflowItem.setOfl_br_code(item.getCkl_br_code());
				overflowItem.setOfl_amount(item.getCkl_amount()-item.getCkl_stock_amount());
				overflowItem.setOfl_unitprice(item.getCkl_unitprice());
				overflowItem.setOfl_remark("");
				overflowItem.setCompanyid(user.getCompanyid());
				of_amount += overflowItem.getOfl_amount();
				of_money += overflowItem.getOfl_amount() * overflowItem.getOfl_unitprice();
				overflowLists.add(overflowItem);
			}
			ba_amount += item.getCkl_amount();
			ba_stockamount += item.getCkl_stock_amount();
			ba_costmoney += item.getCkl_amount() * item.getCkl_unitprice();
			ba_retailmoney += item.getCkl_amount() * item.getCkl_retailprice();
		}
		batch.setBa_amount(ba_amount);
		batch.setBa_stockamount(ba_stockamount);
		batch.setBa_costmoney(ba_costmoney);
		batch.setBa_retailmoney(ba_retailmoney);
		if (lossLists.size() > 0) {//生成报损单
			loss = new T_Stock_Loss();
			loss.setLo_date(DateUtil.getCurrentTime());
			loss.setLo_dp_code(batch.getBa_dp_code());
			loss.setLo_manager(batch.getBa_manager());
			loss.setLo_amount(lo_amount);
			loss.setLo_money(lo_money);
			loss.setLo_remark(batch.getBa_remark());
			loss.setLo_ar_state(CommonUtil.AR_STATE_APPROVED);
			loss.setLo_ar_date(DateUtil.getCurrentTime());
			loss.setLo_isdraft(0);
			loss.setLo_sysdate(DateUtil.getCurrentTime());
			loss.setLo_us_id(batch.getBa_us_id());
			loss.setLo_maker(user.getUs_name());
			loss.setLo_remark("盘点["+batch.getBa_number()+"]生成报损单");
			loss.setCompanyid(user.getCompanyid());
			lossDAO.save(loss, lossLists);
		}
		if (overflowLists.size() > 0) {//生成报溢单
			overflow = new T_Stock_Overflow();
			overflow.setOf_date(DateUtil.getCurrentTime());
			overflow.setOf_dp_code(batch.getBa_dp_code());
			overflow.setOf_manager(batch.getBa_manager());
			overflow.setOf_amount(of_amount);
			overflow.setOf_money(of_money);
			overflow.setOf_remark(batch.getBa_remark());
			overflow.setOf_ar_state(CommonUtil.AR_STATE_APPROVED);
			overflow.setOf_ar_date(DateUtil.getCurrentTime());
			overflow.setOf_isdraft(0);
			overflow.setOf_sysdate(DateUtil.getCurrentTime());
			overflow.setOf_us_id(batch.getBa_us_id());
			overflow.setOf_maker(user.getUs_name());
			overflow.setOf_remark("盘点["+batch.getBa_number()+"]生成报溢单");
			overflow.setCompanyid(user.getCompanyid());
			overflowDAO.save(overflow, overflowLists);
		}
		batch.setBa_isexec(ba_isexec);
		batch.setBa_execdate(DateUtil.getCurrentTime());
		checkDAO.batch_update_exec(batch);
		checkDAO.check_update_exec(ba_isexec, DateUtil.getCurrentTime(), ba_number, user.getCompanyid());
		//更新库存
		List<T_Stock_DataBill> stocks = checkDAO.listStock(ba_number, batch.getBa_dp_code(), user.getCompanyid());
		List<T_Stock_DataBill> add_stocks = new ArrayList<T_Stock_DataBill>();
		List<T_Stock_DataBill> update_stocks = new ArrayList<T_Stock_DataBill>();
		for (T_Stock_DataBill stock : stocks) {
			if(stock.getSd_id() == null){
				stock.setSd_dp_code(batch.getBa_dp_code());
				stock.setSd_init(0);
				stock.setSd_date(DateUtil.getCurrentTime());
				stock.setCompanyid(user.getCompanyid());
				stock.setSd_amount(stock.getBill_amount());
				add_stocks.add(stock);
			}else {
				stock.setSd_amount(stock.getBill_amount());
				update_stocks.add(stock);
			}
		}
		if (add_stocks.size() > 0) {
			dataDAO.save(add_stocks);
		}
		if (update_stocks.size() > 0) {
			dataDAO.update(update_stocks);
		}
	}

	@Override
	public PageData<CheckDiffDto> check_diff_list(Map<String, Object> params) {
		PageData<CheckDiffDto> pageData = checkDAO.check_diff_list(params);
		pageData.setData(checkDAO.check_diff_stat(params));
		return pageData;
	}

	@Override
	public PageData<CheckDiffDto> check_diff_sum(Map<String, Object> params) {
		PageData<CheckDiffDto> pageData = checkDAO.check_diff_sum(params);
		pageData.setData(checkDAO.check_diff_stat(params));
		return pageData;
	}
	
}
